package com.jason.redCherry.common;


import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
import java.util.Random;

/**
 * Function: TODO
 * <p>
 * ClassName:ToolUtil Date: 2013-10-17 上午11:26:03
 *
 * @author chshyin
 * @since JDK 1.6 Copyright (c) 2013, palm-commerce All Rights Reserved.
 */
public class ToolUtil {
    private static String[] week = new String[]{"周一", "周二", "周三", "周四", "周五",
            "周六", "周日"};
    // 地球平均半径 double // 地球平均半径6371.004km
    private static final double EARTH_RADIUS = 6371004;

    private static final String SHORTURL_STR = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    /**
     * 随机生成6位数字的校验码 function:
     *
     * @return
     * @since JDK 1.6
     */
    public static final String randomSmsCode() {

        Random random = new Random();
        StringBuffer sbf = new StringBuffer();
        for (int i = 0; i < 6; i++) {
            String rand = String.valueOf(String.valueOf((random.nextInt(10))));
            sbf.append(rand);
        }

        return sbf.toString();
    }

    /**
     * 获取星期几 周一即为1
     *
     * @return
     */

    public static final String getBeforeThreeMonthDateStr(Date nowDate,
                                                          String dateFormat) {

        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        long nowDateTimeCount = nowDate.getTime();
        long oldDateTimeCount = nowDateTimeCount - (3 * 30 * 24 * 3600 * 1000);
        return sdf.format(new Date(oldDateTimeCount));
    }

    public static int getWeedId(String date) {

        if (date == null) {

            return -1;
        }

        String[] data = null;
        if (date.length() == 8) {// 北京竞彩接口 返回day 格式yyyymmdd

            data = new String[]{date.substring(0, 4), date.substring(4, 6),
                    date.substring(6, 8)};
        } else {// 天津竞彩接口 返回day 格式yyyy-mm-dd
            data = date.split("-");
        }
        if (date.length() < 3) {

            return -1;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, Integer.parseInt(data[0]));// 年份
        calendar.set(Calendar.MONTH, Integer.parseInt(data[1]) - 1);// 月 1月为0
        calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(data[2]));// 日
        // 日历中1代表周日
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        // 周日
        if (dayOfWeek == 1) {

            return 7;
        } else {

            return dayOfWeek - 1;
        }
    }

    // 获取月份的第一天
    public static Date getMonthStart(Date date) {

        return getDate(getDateStr(date, "yyyy-MM"), "yyyy-MM");
    }

    /**
     * @return
     */
    public static final String getWeekStr(int weekId) {
        if (weekId < 1 || weekId > 7) {
            return null;
        }
        return week[weekId - 1];
    }

    /**
     * 比较2个字符串，如果都是null或者都是空字符串则认为相同 function:
     *
     * @param str1
     * @param str2
     * @return
     * @since JDK 1.6
     */

    /**
     * 比较2个时间是否相同，排除空的影响 function:
     *
     * @param d1
     * @param d2
     * @return
     * @since JDK 1.6
     */
    public static boolean isEqualIgnoreEmpty(Date d1, Date d2) {

        if (d1 == null) {

            return d2 == null;
        }

        if (d2 == null) {

            return false;
        }

        return d1.getTime() == d2.getTime();
    }

    /**
     * 格式化时间 function:
     *
     * @param date
     * @return
     * @since JDK 1.6
     */
    public static final String getDateStr(Date date) {
        if (date == null) {
            return null;
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        return df.format(date);

    }

    public static boolean isEmpty(String str) {

        return str == null || str.trim().equals("");
    }

    public static final Date getDate(String date, String formatPattern) {

        if (isEmpty(date)) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(formatPattern);

        try {
            return df.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return null;

    }

    public static String formatDouble(double data) {

        DecimalFormat df = new DecimalFormat("#0.00");

        return df.format(data);
    }

    public static String formatLong(long data) {

        DecimalFormat df = new DecimalFormat("#0");

        return df.format(data);
    }

    public static int intVal(String num) {
        try {
            if (num == null) {
                return 0;
            }
            int value = Integer.parseInt(num.toString());
            return value;
        } catch (Exception e) {
            return 0;
        }

    }

    public static double doubleVal(String num) {
        try {
            if (num == null) {
                return 0;
            }
            double value = Double.parseDouble(num);
            return value;
        } catch (Exception e) {
            return 0;
        }

    }

    public static final String getDateStr(Date date, String formatPattern) {
        if (date == null) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(formatPattern);

        return df.format(date);

    }

    /**
     * 根据时间差计算新的时间 function:
     *
     * @param date
     * @param interval
     * @return
     * @since JDK 1.6
     */
    public static final Date calDate(Date date, long interval) {

        if (date == null || interval == 0) {

            return date;
        }

        return new Date(date.getTime() + interval);
    }

    public static final String formatStr(String str) {

        if (str == null) {

            return "";
        }

        return str;
    }

    /**
     * 计算相差天数时间
     *
     * @param date "yyyy-MM-dd"格式
     * @param day
     * @return "yyyy-MM-dd"格式
     */
    public static String subDayToDate(String date, Integer day) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getDate(date, "yyyy-MM-dd"));
        cal.add(Calendar.DATE, day);
        return getDateStr(cal.getTime(), "yyyy-MM-dd");
    }

    /**
     * 获取date时间之前最早和周次对应的day
     *
     * @param date
     * @param weekStr 周一 - 周日
     * @return yyyy-MM-dd 格式
     */
    public static String getDay(Date date, String weekStr) {
        String matchDateStr = ToolUtil.getDateStr(date, "yyyy-MM-dd");

        int weekId = ToolUtil.getWeedId(matchDateStr);

        String weekDay = ToolUtil.getWeekStr(weekId);

        while (!weekStr.equals(weekDay)) {

            matchDateStr = ToolUtil.subDayToDate(matchDateStr, -1);

            weekDay = ToolUtil.getWeekStr(ToolUtil.getWeedId(matchDateStr));
        }

        return matchDateStr;
    }

    /**
     * @param date
     * @return
     */
    public static final Date getDate(String date) {

        if (date == null || date.trim().equals("")) {

            return null;
        }

        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            return df.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return null;

    }

    public static final Date addDay(Date date, int addDay) {

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, addDay);

        return cal.getTime();
    }

    public static final Date getNextMonthStart(Date date) {

        Calendar cal = Calendar.getInstance();
        cal.setTime(getMonthStart(date));
        cal.add(Calendar.MONTH, 1);

        return cal.getTime();
    }

    /**
     * @param date
     * @return
     */
    public static final String getDateYear(Date date) {

        DateFormat df = new SimpleDateFormat("yyyy");

        return df.format(date);

    }

    /**
     * 返回yyyy-mm-dd格式day
     *
     * @param day yyyymmdd格式
     * @return
     */
    public static String getDay(String day) {
        return new StringBuffer().append(day.substring(0, 4)).append("-")
                .append(day.substring(4, 6)).append("-")
                .append(day.substring(6, 8)).toString();
    }

    public static final boolean isDateEqual(Date d1, Date d2) {

        if (d1 == null) {

            return d2 == null;
        }

        return d1.equals(d2);
    }


    public static final boolean hasEmptyStr(String... strs) {

        boolean result = true;

        if (strs == null) {

            return result;
        }

        for (String str : strs) {

            result = isEmpty(str);

            if (result) {

                break;
            }
        }

        return result;
    }

    /**
     * 算地球上任意两点(经纬度)距离 function:
     *
     * @param lng0 第一点经度
     * @param lat0 第一点纬度
     * @param lng1 第二点经度
     * @param lat1 第二点纬度
     * @return 返回距离 单位：米
     * @since JDK 1.6
     */
    public static double getDistanceHav(double lng0, double lat0, double lng1,
                                        double lat1) {

        // "用haversine公式计算球面两点间的距离。"
        // # 经纬度转换成弧度

        lat0 = Math.toRadians(lat0);
        lat1 = Math.toRadians(lat1);
        lng0 = Math.toRadians(lng0);
        lng1 = Math.toRadians(lng1);

        double dlng = Math.abs(lng0 - lng1);
        double dlat = Math.abs(lat0 - lat1);

        double h = hav(dlat) + Math.cos(lat0) * Math.cos(lat1) * hav(dlng);

        double distance = 2 * EARTH_RADIUS * Math.asin(Math.sqrt(h));

        return distance;
    }

    // World Geodetic System ==> Mars Geodetic System
    public static double[] transform(double wgLat, double wgLon) {

        double a = 6378245.0;
        double ee = 0.00669342162296594323;

        double mgLat = 0;
        double mgLon = 0;

        if (outOfChina(wgLat, wgLon)) {
            mgLat = wgLat;
            mgLon = wgLon;
            return new double[]{mgLat, mgLon};
        }
        double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
        double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
        double radLat = wgLat / 180.0 * Math.PI;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0)
                / ((a * (1 - ee)) / (magic * sqrtMagic) * Math.PI);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * Math.PI);
        mgLat = wgLat + dLat;
        mgLon = wgLon + dLon;

        return new double[]{mgLat, mgLon};
    }

    // 判断坐标是否在中国
    private static boolean outOfChina(double lat, double lon) {
        if (lon < 72.004 || lon > 137.8347)
            return true;
        return lat < 0.8293 || lat > 55.8271;
    }

    private static double transformLat(double x, double y) {
        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y
                + 0.2 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x
                * Math.PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin(y / 3.0
                * Math.PI)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(y / 12.0 * Math.PI) + 320 * Math.sin(y
                * Math.PI / 30.0)) * 2.0 / 3.0;
        return ret;
    }

    private static double transformLon(double x, double y) {
        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
                * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x
                * Math.PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin(x / 3.0
                * Math.PI)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(x / 12.0 * Math.PI) + 300.0 * Math.sin(x
                / 30.0 * Math.PI)) * 2.0 / 3.0;
        return ret;
    }

    private static double hav(double theta) {

        double s = Math.sin(theta / 2);

        return s * s;
    }

    /**
     * 根据距离计算弧度 function:
     *
     * @param distance 距离，米
     * @return 经纬度相差弧度
     * @since JDK 1.6
     */
    public static double getDistanceDegrees(double longt1, double lat1,
                                            double distance) {

        // double dlat = distance / EARTH_RADIUS;
        // # 弧度转换成角度
        // return Math.toDegrees(dlat);

        double a = (180 * distance)
                / (Math.PI * EARTH_RADIUS * Math.cos(lat1 * Math.PI / 180));

        return a;
    }

    /**
     * d1 + d2 function:
     *
     * @param d1
     * @param d2
     * @return
     * @since JDK 1.6
     */
    public static double add(double d1, double d2) {

        BigDecimal b1 = new BigDecimal(String.valueOf(d1));
        BigDecimal b2 = new BigDecimal(String.valueOf(d2));

        return b1.add(b2).doubleValue();
    }

    /**
     * d1 - d2 function:
     *
     * @param d1
     * @param d2
     * @return
     * @since JDK 1.6
     */
    public static double subtract(double d1, double d2) {

        BigDecimal b1 = new BigDecimal(String.valueOf(d1));
        BigDecimal b2 = new BigDecimal(String.valueOf(d2));

        return b1.subtract(b2).doubleValue();
    }

    /**
     * d1 * d2 ,保留scale 位小数 function:
     *
     * @param d1
     * @param d2
     * @param scale
     * @return
     * @since JDK 1.6
     */
    public static double multiply(double d1, double d2, int scale) {

        BigDecimal b1 = new BigDecimal(String.valueOf(d1));
        BigDecimal b2 = new BigDecimal(String.valueOf(d2));

        return b1.multiply(b2)
                .divide(new BigDecimal(1), scale, BigDecimal.ROUND_DOWN)
                .doubleValue();
    }

    /**
     * d1 / d2 ,保留scale 位小数 function:
     *
     * @param d1
     * @param d2
     * @param scale
     * @return
     * @since JDK 1.6
     */
    public static double divide(double d1, double d2, int scale) {

        BigDecimal b1 = new BigDecimal(String.valueOf(d1));
        BigDecimal b2 = new BigDecimal(String.valueOf(d2));

        return b1.divide(b2, scale, BigDecimal.ROUND_DOWN).doubleValue();
    }

    /**
     * d1 * d2 function:
     *
     * @param d1
     * @param d2
     * @return
     * @since JDK 1.6
     */
    public static double multiply(double d1, double d2) {

        BigDecimal b1 = new BigDecimal(String.valueOf(d1));
        BigDecimal b2 = new BigDecimal(String.valueOf(d2));

        return b1.multiply(b2).doubleValue();
    }

    public static String formatPhone(String phone) {

        if (phone == null) {

            return "";
        }

        if (phone.length() < 7) {

            return phone;
        }

        return phone.substring(0, 3)
                + phone.substring(phone.length() - 4, phone.length());
    }

    public static String formatPhoneShow(String phone) {

        if (phone == null) {

            return "";
        }

        if (phone.length() < 6) {

            return phone;
        }

        return phone.substring(0, 3) + "***"
                + phone.substring(phone.length() - 3, phone.length());
    }

    public static String getDayStart(Date date) {

        String dayStr = ToolUtil.getDateStr(date, "yyyy-MM-dd");

        return dayStr + " 00:00:00";
    }

    public static String getDayStr(Date date, int addDay) {

        Calendar cal = Calendar.getInstance();

        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);

        cal.add(Calendar.DATE, addDay);

        return getDateStr(cal.getTime());
    }

	/*public static String getShortUrl(String url) {

		String[] shortUrls = shortUrl(url);

		Random random = new Random();
		// 随机取一个结果，防止解密
		int index = random.nextInt(4);

		return shortUrls[index];
	}*/

/*	private static String[] shortUrl(String url) {
        // 可以自定义生成 MD5 加密字符传前的混合 KEY
		String key = "ssports.com";
		// 对传入网址进行 MD5 加密
		String hex = MD5.Md532(url + key);

		String[] resUrl = new String[4];
		for (int i = 0; i < 4; i++) {
			// 把加密字符按照 8 位一组 16 进制与 0x3FFFFFFF 进行位与运算
			String sTempSubString = hex.substring(i * 8, i * 8 + 8);

			// 这里需要使用 long 型来转换，因为 Inteper .parseInt() 只能处理 31 位 , 首位为符号位 ,
			// 如果不用long ，则会越界
			long lHexLong = 0x3FFFFFFF & Long.parseLong(sTempSubString, 16);
			String outChars = "";
			for (int j = 0; j < 6; j++) {
				// 把得到的值与 0x0000003D 进行位与运算，取得字符数组 chars 索引
				int index = (int) (0x0000003D & lHexLong);
				// 把取得的字符相加
				outChars += SHORTURL_STR.charAt(index);
				// 每次循环按位右移 5 位
				lHexLong = lHexLong >> 5;
			}
			// 把字符串存入对应索引的输出数组
			resUrl[i] = outChars;
		}
		return resUrl;
	}*/

	/*public static void main(String[] args) {
        // 北京 北纬39.55 东经116.24
		double lng0 = 116.46933339451;
		// 0.001052
		// 116.447411
		// 116.447151
		double lat0 = 39.938282307702;
		// 宜昌 北纬30.42 东经111.17
		double lng1 = 116.463288;
		double lat1 = 39.937624;

		System.out.println(getDistanceHav(lng0, lat0, lng1, lat1));
		// 116.447729,39.948491
		System.out.println(getDistanceDegrees(116.446359, 39.948498, 112));

		System.out.println(formatDouble(.00));

		double[] dd = transform(lat0, lng0);
		System.out.println(dd[0] + ":" + dd[1]);

		System.out.println(getDistanceHav(dd[1], dd[0], lng1, lat1));

		System.out.println(formatPhoneShow("13810318552"));

		System.out.println(1 - 0.8);
		System.out.println(0.8 * 100);

		System.out.println(getDayStart(new Date()));
		System.out.println(getDayStr(new Date(), 1));
		System.out.println(ToolUtil.divide(12, 12, 4));

		System.out.println(SHORTURL_STR.length());

		String url = "http://www.baidu.com";

		for (int i = 0; i < 10; i++) {
			System.out.println(getShortUrl(url));
		}

		Map<String, String> params = new HashMap<String, String>();
		// params.put("url",
		// "http://localhost:8080/nx_unicom_h5/reward_showReward.action");
		params.put("activityId", "1601141431111000079");
		// params.put("result", "1");
		*//*
         * System.out.println(formatParams(params));
		 * 
		 * String paramStr =
		 * "eyJhY3Rpdml0eUlkIjoiMTYwMTE0MTQzMTExMTAwMDA3OSJ9";//
		 * formatParams(params); System.out.println(paramStr); params =
		 * parseParams(paramStr); System.out.println(params);
		 *//*

	}*/

	/*public static String formatNickName(String nickName) {

		Charset charset = Charset.forName("utf-8");

		byte[] b_text = nickName.getBytes(charset);

		for (int i = 0; i < b_text.length; i++) {
			if ((b_text[i] & 0xF8) == 0xF0) {

				byte[] bb = "^_^!".getBytes();

				for (int j = 0; j < 4; j++) {
					b_text[i + j] = bb[j];
				}
				i += 3;
			}
		}

		return new String(b_text, charset);
	}*/

    public static String getBasePath() {
        String path = "";
        Properties proper = new Properties();
        try {
            proper.load(ToolUtil.class
                    .getResourceAsStream("/config.properties"));
            path = proper.get("img_basePath").toString();
        } catch (IOException e) {
            System.out.println("读取配置文件错误");
            e.printStackTrace();
        }
        return path;
    }

    /**
     * @param @return 设定文件
     * @return String 返回类型
     * @throws
     * @Title: getImageUrl
     * @Description: TODO(获取图片前缀)
     */
    public static String getImageUrl() {
        String path = "";
        Properties proper = new Properties();
        try {
            proper.load(ToolUtil.class
                    .getResourceAsStream("/config.properties"));
            path = proper.get("imgUrl").toString();
        } catch (IOException e) {
            System.out.println("读取配置文件错误");
            e.printStackTrace();
        }
        return path;
    }

    public static String getImgBasePath() {
        String path = "";
        Properties proper = new Properties();
        try {
            proper.load(ToolUtil.class
                    .getResourceAsStream("/config.properties"));
            path = proper.get("img_basePath").toString();
        } catch (IOException e) {
            System.out.println("读取配置文件错误");
            e.printStackTrace();
        }
        return path;
    }


    public static String upVersion(String version) {

        String[] v = version.split("\\.");

        int t1 = Integer.parseInt(v[0]);
        int t2 = Integer.parseInt(v[1]);
        int t3 = Integer.parseInt(v[2]);

        int t = t1 * 100 + t2 * 10 + t3;

        t++;

        int v1 = t / 100;
        int v2 = t / 10;
        int v3 = t % 10;

        String vv = String.format("%d.%d.%d", v1, v2, v3);
        return vv;
    }

    public static String getNextValue() {
        String id = java.util.UUID.randomUUID().toString();
        return id;
    }


    public static void main(String args[]) {
        String v = ToolUtil.upVersion("0.0.9");
        System.out.println(v);
    }

	/*
	 * public static String formatParams(Map<String, String> map) {
	 * 
	 * if (map == null || map.isEmpty()) {
	 * 
	 * return ""; }
	 * 
	 * String content = JsonHelper.toJSONString(map);
	 * 
	 * String str = Base64.encode(content.getBytes(Charset.forName("utf8")))
	 * .replace("/", "__");
	 * 
	 * return str; }
	 * 
	 * @SuppressWarnings("unchecked") public static Map<String, String>
	 * parseParams(String paramStr) {
	 * 
	 * if (isEmpty(paramStr)) {
	 * 
	 * return new HashMap<String, String>(); }
	 * 
	 * String str = paramStr.replace("__", "/");
	 * 
	 * String jsonStr = new String(Base64.decode(str), Charset.forName("utf8"));
	 * log.info(LogFormat.formatMsg("ToolUtil.parseParams", jsonStr, null));
	 * return JsonHelper.parseObject(jsonStr, Map.class); }
	 */

}
